package main

import "fmt"

func main() {
	done := make(chan struct{})
	defer close(done)
	s := []int{1, 2, 3, 4, 5, 6}
	stream := generater(done, s...)

	// 对队列里的每个数计算 2*x^2 + 6
	s = nil
	result := add(done, multiply(done, pow(done, stream, 2), 2), 6)
	for i := range result {
		s = append(s, i)
	}

	fmt.Println(s)
}

func generater(done <-chan struct{}, ints ...int) <-chan int {
	result := make(chan int)
	go func() {
		defer close(result)
		for _, in := range ints {
			select {
			case result <- in:
			case <-done:
				return
			}

		}

	}()

	return result
}

func multiply(done <-chan struct{}, stream <-chan int, multiplier int) <-chan int {
	result := make(chan int)
	go func() {
		defer close(result)
		for in := range stream {
			select {
			case result <- in * multiplier:
			case <-done:
				return
			}
		}
	}()
	return result
}

func add(done <-chan struct{}, stream <-chan int, additive int) <-chan int {
	result := make(chan int)
	go func() {
		defer close(result)
		for in := range stream {
			select {
			case result <- in + additive:
			case <-done:
				return
			}
		}
	}()
	return result
}

func power2(data, i int) int {
	if i == 0 {
		return 1
	} else {
		return data * power2(data, i-1)
	}
}

func pow(done <-chan struct{}, stream <-chan int, index int) <-chan int {
	result := make(chan int)
	go func() {
		defer close(result)
		for in := range stream {
			select {
			case result <- power2(in, index):
			case <-done:
				return
			}
		}
	}()
	return result
}
